using System.Linq;
using Magiq.Sql.Tests.TestModel;
using Magiq.Tests.Support;
using NUnit.Framework;

namespace Magiq.Sql.Tests
{
    [TestFixture]
    public class CollectionTest
    {
        #region Setup/Teardown

        [SetUp]
        public void SetUp()
        {
            MagiqToSqlTestConfigurator.Current.SetUp();
            domain = new CollectionTestDomain();
            MagiqToSqlTestConfigurator.Current.Persist(domain.ChildItems);
            MagiqToSqlTestConfigurator.Current.Persist(domain.Parents);
            domain.AddRelations();
            MagiqToSqlTestConfigurator.Current.Reload();
            parents = MagiqToSqlTestConfigurator.Current.GetQueryable<Parent>();
        }

        [TearDown]
        public void TearDown()
        {
            MagiqToSqlTestConfigurator.Current.TearDown();
        }

        #endregion

        private CollectionTestDomain domain;
        private IQueryable<Parent> parents;

        [Test]
        public void ShouldDeleteFromCollection()
        {
            var collection = parents.ToList().First().Items.Query();
            var items = collection.Where(x => x.Name == "lala");
            var count = items.Count();
            items.Delete().Should(Be.EqualTo(count));
        }

        [Test]
        public void ShouldInsertIntoNoQueryableButDeferredEntitySet()
        {
            var dest = parents.ToList().First().Items;
            //if I apply count() to items, linq-to-sql loads the entire collection and it became not deferred
            var prevCount = dest.Query().Count();

            var count = parents.Count();
            var insertCount = dest.From(parents).Insert(x => new ChildItem
                                                                 {
                                                                     Name = x.Name + " child"
                                                                 });
            insertCount.Should(Be.EqualTo(count));
            dest.Count().Should(Be.EqualTo(prevCount + insertCount));
        }

        [Test]
        public void ShouldInsertIntoQueryableCollection()
        {
            var dest = parents.ToList().First().Items.Query();
            var prevCount = dest.Count();
            var count = parents.Count();
            var insertCount = dest.From(parents).Insert(x => new ChildItem
                                                                 {
                                                                     Name = x.Name + " child"
                                                                 });
            insertCount.Should(Be.EqualTo(count));
            dest.Count().Should(Be.EqualTo(prevCount + insertCount));
        }

        [Test]
        public void ShouldNotInsertIntoNotDeferredEntitySet()
        {
            var dest = parents.ToList().First().Items;
            dest.Count(); //this make Destination not deferred.

            dest.From(parents).Insert(x => new ChildItem
                                               {
                                                   Name = x.Name + " child"
                                               });
            MagiqMock.AssertWasUsed();
        }

        [Test]
        public void ShouldMakeEntitySetToQueryable()
        {
            var queryableCollection = parents.ToList().First()
                .Items.Query().Where(x => x.Name == "lala").OrderBy(x => x.Id);
            var enumerableCollection = parents.ToList().First()
                .Items.Where(x => x.Name == "lala").OrderBy(x => x.Id);

            Assert.AreNotEqual(queryableCollection.GetType(), enumerableCollection.GetType());

            var list1 = queryableCollection.ToList();
            var lisTestClass2 = enumerableCollection.ToList();

            for (var i = 0; i < list1.Count; i++)
                list1[i].Id.Should(Be.EqualTo(lisTestClass2[i].Id));
        }

        [Test]
        public void ShouldUpdateCollection()
        {
            var collection = parents.ToList().First().Items.Query();
            var items = collection.Where(x => x.Name == "lala");
            var count = items.Count();
            items.Set(x => x.Name, "lele").Update().Should(Be.EqualTo(count));
        }
    }
}